package com.zmn.mcc.cas.server.controller.cas;

import com.zmn.common.dto2.ResponseDTO;
import com.zmn.mcc.business.interfaces.staff.StaffBService;
import com.zmn.mcc.cache.StaffCache;
import com.zmn.mcc.cas.model.LoginStaff;
import com.zmn.mcc.cas.server.StaffLoginService;
import com.zmn.mcc.cas.server.shiro.StaffShiroRealm;
import com.zmn.mcc.cas.web.StaffAdminService;
import com.zmn.mcc.common.constant.DingTalkConsts;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * @author nowind
 * @since 16/1/3 21:04
 */
@Controller
@RequestMapping("/")
public class CasListController {


    private Logger logger = LoggerFactory.getLogger(CasListController.class);

    @Resource
    StaffLoginService staffLoginService;

    @Resource
    StaffBService staffBService;

//    @Resource
//    private ShiroTokenManager shiroTokenManager;

    /**
     * 主页面
     */
   /* @RequestMapping(value = {"index", "/"})
    public ModelAndView index(HttpServletRequest request) {
        //从数据库查询最新的实体，解决修改密码框弹出时获取shiro中initialPassword没有发生变化的问题
        McStaff shiroStaff = getMcStaff();
        McStaff staff = staffService.findByKey(shiroStaff.getStaffId());
        staff = staff == null ? shiroStaff : staff;
        ModelAndView mav = new ModelAndView("index");
        mav.addObject("staffName", staff.getRealName());
        *//*mav.addObject("initialPassword", staff.getInitialPassword());*//*
        return mav;
    }*/

    @Resource
    private StaffShiroRealm staffShiroRealm;

    private static final String PARAMETER_AUTHCODE= "authCode";

    private static final String PARAMETER_CUBEFLAG= "cubeFlag";

    /**
     * 当前登录用户权限信息
     *
     * @return
     */
    @RequestMapping("/cas/client/myPermit")
    @ResponseBody
    public ResponseDTO myPermit() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        Method method = ReflectUtils.findDeclaredMethod(staffShiroRealm.getClass(), "getAuthorizationInfo", new Class[]{PrincipalCollection.class});
        method.setAccessible(true);
        AuthorizationInfo info = (AuthorizationInfo) method.invoke(staffShiroRealm, SecurityUtils.getSubject().getPrincipals());
        Map map = new HashMap<>(16);
        map.put("roles", info.getRoles());
        ArrayList<String> list = new ArrayList(info.getStringPermissions());
        Collections.sort(list);
        map.put("permissions", list);
        map.put("staff", StaffAdminService.currentStaff());
        return ResponseDTO.success(map);

    }

    /**
     * console页面
     */
    @RequestMapping(value = {"console"})
    public ModelAndView console(HttpServletRequest request) {
        ModelAndView mav = new ModelAndView("console");
        return mav;
    }

    /**
     * @return
     */
    @RequestMapping(value = "cas/page")
    public ModelAndView info(HttpServletRequest request) {
        LoginStaff staff = StaffAdminService.currentStaff();
        ModelAndView mav = new ModelAndView("cas/page");
        mav.addObject("staffName", staff.getRealName());
        return mav;
    }

    /**
     * 登录页
     */
    @RequestMapping(value = "login")
    public ModelAndView loginDetail(HttpServletRequest request, HttpServletResponse response) {

        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession(false);
        // 登录错误信息
        String message = "";
        if (session != null && session.getAttribute("message") != null) {
            message = session.getAttribute("message").toString();
            session.removeAttribute("message");
        }
        ModelAndView mav;
        if (staffLoginService.isEnableAccountLogin()) {
            mav = new ModelAndView("cas/login");
        } else {
            mav = new ModelAndView("cas/qrcode_login");

            mav.addObject("appId", DingTalkConsts.DD_APP_ID);
            mav.addObject("appSecret", DingTalkConsts.DD_APP_SECRET);
        }
        mav.addObject("message", message);
        // 重定向页面
        mav.addObject("redirectUrl", request.getParameter("redirectUrl"));
        return mav;
    }

    /**
     * 临时登录页
     */
    @RequestMapping(value = "tmpLogin")
    public ModelAndView tmpLogin(HttpServletRequest request, HttpServletResponse response, @RequestParam(value="logId")Integer logId) {
        ModelAndView mav;
        if (StaffCache.SPECIAL_STAFF_MAP.containsKey(logId)) {
            mav = new ModelAndView("cas/tmpLogin");
            mav.addObject("logId", logId);
            return mav;
        }

        if (staffBService.enableLogin(logId)) {
            mav = new ModelAndView("cas/tmpLogin");
        } else {
            mav = new ModelAndView("cas/error");
            mav.addObject("logId", logId);
        }
        return mav;
    }

    /**
     * 钉钉免登录
     */
    @RequestMapping(value = "authCodeLogin")
    public ModelAndView authCodeLogin(HttpServletRequest request, HttpServletResponse response) {
        String authCode = request.getParameter(PARAMETER_AUTHCODE);
        String cubeFlag = request.getParameter(PARAMETER_CUBEFLAG);
        logger.info("进入方法authCodeLogin");
        ModelAndView mav = new ModelAndView("cas/authCodeLogin");
        mav.addObject("corpId", DingTalkConsts.DING_TALK_APP_CORP_ID);
        if (StringUtils.isNotEmpty(authCode)) {
            mav.addObject(PARAMETER_AUTHCODE, authCode);
        }
        if (StringUtils.isNotEmpty(cubeFlag)) {
            mav.addObject(PARAMETER_CUBEFLAG, cubeFlag);
        }
        return mav;
    }

    /**
     * 钉钉免登录-临时跳转
     */
    @RequestMapping(value = "jumpLogin")
    public ModelAndView jumpLogin(HttpServletRequest request, HttpServletResponse response) {
        String authCode = request.getParameter(PARAMETER_AUTHCODE);
        String cubeFlag = request.getParameter(PARAMETER_CUBEFLAG);
        logger.info("进入方法jumpLogin");
        ModelAndView mav = new ModelAndView("cas/jumpLogin");
        if (StringUtils.isNotEmpty(authCode)) {
            mav.addObject(PARAMETER_AUTHCODE, authCode);
        }
        if (StringUtils.isNotEmpty(cubeFlag)) {
            mav.addObject(PARAMETER_CUBEFLAG, cubeFlag);
        }
        return mav;
    }

    /**
     * 绑定页
     */
    @RequestMapping(value = "bind")
    public ModelAndView bind(HttpServletRequest request, HttpServletResponse response) {
        ModelAndView mav = new ModelAndView("cas/bind");
        mav.addObject("redirectUrl", request.getParameter("redirectUrl"));
        mav.addObject("dTalkUserId", request.getParameter("dTalkUserId"));
        return mav;
    }

    /**
     * 被踢出页面
     *
     * @return
     */
    @RequestMapping(value = "kickout")
    public ModelAndView kickOut() {

        ModelAndView mav = new ModelAndView("cas/kickout");
        return mav;
    }

    /**
     * 无权限页
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "untitled")
    public ModelAndView untitledDetail(HttpServletRequest request) {

        ModelAndView mav = new ModelAndView("cas/untitled");
        return mav;
    }


    /**
     * 修改密码
     */
    @RequestMapping(value = "/cas/pwd")
    public ModelAndView pwdDetail(HttpServletRequest request) {

        LoginStaff staff = StaffAdminService.currentStaff();

        ModelAndView mav = new ModelAndView("cas/pwd/updatePwd");
        mav.addObject("staff", staff);
        //针对强制修改密码的情况，复用统一页面
        mav.addObject("flag", request.getParameter("flag"));

        return mav;
    }

    /**
     * Shiro验证失败，抛出UnauthorizedException异常
     *
     * @param request
     * @param e
     * @return
     */
    @ExceptionHandler({UnauthorizedException.class})
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public ModelAndView processUnauthenticatedException(NativeWebRequest request, UnauthorizedException e) {
        ModelAndView mav = new ModelAndView("cas/untitled");
        return mav;
    }

    /**
     * 获取登录用户
     *
     * @return
     */
//    protected McStaff getMcStaff() {
//        UserTokenDO token = shiroTokenManager.getUserToken();
//        McStaff staff = JSONObject.parseObject(token.getUserObj(), McStaff.class);
//        return staff;
//    }
}
